const Koa = require('koa');
const app = new Koa();
const json = require('koa-json');
const onerror = require('koa-onerror');
const bodyParser = require('koa-bodyparser');
const logger = require('koa-logger');
const session = require('koa-session');
const render = require('koa-art-template');
const path = require('path');
const fs = require('fs');
const morgan = require('koa-morgan');

// 引入路由中间件
const music = require('./routes/music');
const user = require('./routes/user');

// error handler
onerror(app);

// 模版渲染
render(app, {
    root: path.join(__dirname, 'views'),
    extname: '.html',
    debug: process.env.NODE_PATH !== 'production'
});

// 中间件使用列表
// app.use(bodyParser({enableTypes: ['json', 'form', 'text']}));
app.use(require('koa-formidable')({
    // 设置上传目录，否则在用户的temp目录下
    uploadDir: path.join(__dirname, './public/files'),
    // 默认根据文件算法生成hash字符串（文件名），无后缀
    keepExtensions: true
}));

app.use(json());
app.use(logger());

// 优雅的处理异常
const rewriteUrl = require('./middleware/rewrite');
const error = require('./middleware/error');
app.use(error());
// 为了给static重写URL
app.use(rewriteUrl(require('./configure/rewriteUrl')));

// 处理静态资源
app.use(require('koa-static')(__dirname + '/public'));

// logger
app.use(async (ctx, next) => {
    const start = new Date();
    await next();
    const ms = new Date() - start;
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
});

const ENV = process.env.NODE_ENV;
if (ENV !== 'production') {
    // 开发环境 / 测试环境
    app.use(morgan('dev'));
} else {
    // 线上环境
    const logFileName = path.join(__dirname, 'logs', 'access.log');
    const writeStream = fs.createWriteStream(logFileName, {flags: 'a'});
    app.use(morgan('combined', {stream: writeStream}));
}

// 处理session
// 数字签名的加密依赖
app.keys = ['session-key'];
// 配置session的store
const store = {  // 把session数据作为内存处理,当然,还有配置数据库存储的方式
    storage: {},
    set(key, session) {
        this.storage[key] = session;
    },
    get(key) {
        return this.storage[key];
    },
    destroy(key) {
        delete this.storage[key];
    }
};
app.use(session({store}, app));

// 拦截用户,如果用户没有登录,给与一个简单页面,让用户登录
const checkLogin = require('./middleware/checkLogin');
app.use(checkLogin);

// 挂载了session和判断了权限，必须在每次请求挂载新的数据和视图的桥梁(在session之后)
app.use(async (ctx, next) => {
    // 让session中的user,与art-template视图产生联系
    ctx.state.user = ctx.session.user;
    // 在模板处理中  {{ user }}
    // 放行
    await next();
});

// routes
app.use(music.routes(), music.allowedMethods());
app.use(user.routes(), user.allowedMethods());

// error-handling
app.on('error', (err, ctx) => {
    console.error('server error', err, ctx)
});

module.exports = app;
